home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
hity wydania
/
Ubuntu 9.10 PL
/
karmelkowy-koliberek-9.10-netbook-remix-PL.iso
/
casper
/
filesystem.squashfs
/
usr
/
lib
/
ubiquity
/
bin
/
ubiquity
Wrap
Text File
|
2009-10-28
|
16KB
|
460 lines
#!/usr/bin/python
'''
Installer
This is a installer program for a Ubuntu or Metadistros Live system.
This is the main program, but there are also a couple of libraries to
help it to work, such as the frontend.
The way it works is simple. It detects the frontend to use, then
load the module for that frontend. After that, it makes some calls
through the frontend in order to get the info necessary to install.
Once it has the info, partitioning, format, copy the distro to the disk
and configure everything.
'''
import sys
import os
import errno
import fcntl
import shutil
import syslog
import atexit
import optparse
import subprocess
sys.path.insert(0, '/usr/lib/ubiquity')
from ubiquity import misc
from ubiquity import im_switch
VERSION = '2.0.8'
TARGET = '/target'
LOCKFILE = '/var/lock/ubiquity'
lock = None
def distribution():
"""Returns the name of the running distribution."""
proc = subprocess.Popen(['lsb_release', '-is'], stdout=subprocess.PIPE)
return proc.communicate()[0].strip()
def disable_autologin():
import traceback
# Reverse actions of user-setup-apply.
for name in ('/etc/gdm/custom.conf', '/etc/kde4/kdm/kdmrc'):
if os.path.exists('%s.oem' % name):
try:
os.rename('%s.oem' % name, name)
except OSError:
traceback.print_exc()
def open_terminal():
"""Set up the terminal to run ubiquity's debconf frontend."""
# Set up a framebuffer and start bterm if debian-installer/framebuffer
# says to do so. See
# rootskel/src/lib/debian-installer-startup.d/S40framebuffer-module-linux-x86.
# TODO: more careful architecture handling
import debconf
if 'UBIQUITY_BTERM' not in os.environ:
os.environ['UBIQUITY_BTERM'] = '1'
framebuffer = False
dccomm = subprocess.Popen(['debconf-communicate',
'-fnoninteractive', 'ubiquity'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, close_fds=True)
try:
dc = debconf.Debconf(read=dccomm.stdout, write=dccomm.stdin)
try:
if dc.get('debian-installer/framebuffer') == 'true':
framebuffer = True
except debconf.DebconfError:
pass
finally:
dccomm.stdin.close()
dccomm.wait()
if framebuffer:
def fb_has(substring):
try:
fb = open('/proc/fb')
except IOError:
return False
try:
for line in fb:
if substring in line:
return True
finally:
fb.close()
return False
got_fb = False
if fb_has('VESA'):
got_fb = True
devnull = open('/dev/null', 'w')
if not got_fb:
subprocess.call(['modprobe', '-q', 'vesafb'],
stdout=devnull, stderr=devnull)
if fb_has(''):
got_fb = True
if not got_fb:
subprocess.call(['modprobe', '-q', 'vga16fb'],
stdout=devnull, stderr=devnull)
if fb_has(''):
got_fb = True
if got_fb:
if not os.path.isdir('/sys/class/graphics/fbcon'):
subprocess.call(['modprobe', '-q', 'fbcon'],
stdout=devnull, stderr=devnull)
# TODO: import debian-installer-utils and use update-dev?
subprocess.call(['udevadm', 'settle'])
devnull.close()
if os.path.exists('/dev/fb0'):
bterm_args = ['bterm',
'-f', '/usr/share/ubiquity/unifont.bgf', '--']
bterm_args.extend(sys.argv)
os.execvp('bterm', bterm_args)
# Start a new session and start a controlling terminal. Approach loosely
# borrowed from util-linux.
if 'UBIQUITY_CTTY' not in os.environ:
os.environ['UBIQUITY_CTTY'] = '1'
import fcntl
import termios
try:
os.setsid()
except OSError:
pass
ttyn = os.ttyname(0)
tty = os.open(ttyn, os.O_RDWR | os.O_NONBLOCK)
flags = fcntl.fcntl(tty, fcntl.F_GETFL)
fcntl.fcntl(tty, fcntl.F_SETFL, flags)
# Leave stderr alone in the following; it's already redirected to
# our log file.
for i in range(tty):
if i != 2:
os.close(i)
for i in range(2):
if tty != i:
os.dup2(tty, i)
if tty >= 3:
os.close(tty)
fcntl.ioctl(0, termios.TIOCSCTTY, 1)
def start_debconf():
"""debconf_ui needs to run within a debconf frontend."""
if 'DEBIAN_HAS_FRONTEND' in os.environ:
# debconf already started, so just clean up the configuration file
# if any (debconf has already read it by now).
if 'DEBCONF_SYSTEMRC' in os.environ:
try:
os.unlink(os.environ['DEBCONF_SYSTEMRC'])
except OSError:
pass
return
print >>sys.stderr, "debconf_ui selected; starting debconf frontend"
if 'DEBCONF_USE_CDEBCONF' not in os.environ:
# This is rather unsatisfactory. Perhaps it would be better to
# have a custom debconf program, a bit like dpkg-reconfigure.
import tempfile
debconfrc_fd, debconfrc = tempfile.mkstemp()
os.chmod(debconfrc, 0644)
debconfrc_file = os.fdopen(debconfrc_fd, 'w')
orig_debconfrc = open('/etc/debconf.conf')
state = 0
for line in orig_debconfrc:
if (state == 0 and
line.rstrip('\n') and not line.startswith('#')):
state = 1
elif state == 1 and not line.rstrip('\n'):
print >>debconfrc_file, 'Reshow: true'
state = 2
print >>debconfrc_file, line,
orig_debconfrc.close()
debconfrc_file.close()
os.environ['DEBCONF_SYSTEMRC'] = debconfrc
os.environ['DEBCONF_PACKAGE'] = 'ubiquity'
else:
os.environ['DEBCONF_SHOWOLD'] = 'true'
# TODO: need to set owner somehow
import debconf
debconf.runFrontEnd() # re-execs this program
def install(frontend=None, query=False):
'''install(frontend=None) -> none
Get the type of frontend to use and load the module for that.
If frontend is None, defaults to the first of mythbuntu_ui,
gtk_ui, kde_ui, and debconf_ui that exists.
'''
if frontend is None:
frontends = ['mythbuntu_ui', 'gtk_ui', 'kde_ui', 'debconf_ui']
else:
frontends = [frontend]
chosen = None
mod = __import__('ubiquity.frontend', globals(), locals(), frontends)
for f in frontends:
if hasattr(mod, f):
chosen = f
ui = getattr(mod, f)
# Noninteractive implies automatic mode.
if f == 'noninteractive':
os.environ['UBIQUITY_AUTOMATIC'] = '1'
# Migration Assistant does not support KDE.
if f == 'kde_ui':
if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ:
del os.environ['UBIQUITY_MIGRATION_ASSISTANT']
break
else:
raise AttributeError, ('No frontend available; tried %s' %
', '.join(frontends))
os.environ['UBIQUITY_FRONTEND'] = chosen
if query:
print >> sys.__stdout__, os.environ['UBIQUITY_FRONTEND']
sys.exit(0)
unmount_target()
distro = distribution().lower()
wizard = ui.Wizard(distro)
if os.environ['UBIQUITY_FRONTEND'] == 'debconf_ui':
open_terminal()
start_debconf()
ret = wizard.run()
copy_debconf()
unmount_target()
if ret == 10:
wizard.do_reboot()
def copy_debconf():
"""Copy a few important questions into the installed system."""
if not TARGET:
return
targetdb = TARGET + '/var/cache/debconf/config.dat'
# xserver-xorg is temporary, pending a rework of bullet-proof-x; but
# note that xserver-xorg/config/inputdevice/keyboard/* is still needed
for q in ('^console-setup/','^xserver-xorg/'):
misc.execute('debconf-copydb', 'configdb', 'targetdb', '-p', q,
'--config=Name:targetdb', '--config=Driver:File',
'--config=Filename:%s' % targetdb)
def unmount_target():
if not TARGET:
return
paths = []
mounts = open('/proc/mounts')
for line in mounts:
path = line.split(' ')[1]
if path == TARGET or path.startswith(TARGET + '/'):
paths.append(path)
mounts.close()
paths.sort()
paths.reverse()
for path in paths:
misc.execute('umount', path)
def prepend_path(directory):
if 'PATH' in os.environ and os.environ['PATH'] != '':
os.environ['PATH'] = '%s:%s' % (directory, os.environ['PATH'])
else:
os.environ['PATH'] = directory
def release_lock():
global lock
try:
os.unlink(LOCKFILE)
except OSError:
pass
if lock is not None:
lock.close()
lock = None
def acquire_lock():
global lock
lock = open(LOCKFILE, 'w')
try:
fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError, e:
if e.errno in (errno.EACCES, errno.EAGAIN, errno.EWOULDBLOCK):
print "Ubiquity is already running!"
sys.exit(1)
raise
atexit.register(release_lock)
fcntl.fcntl(lock, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
print >>lock, os.getpid()
lock.flush()
os.fsync(lock.fileno())
def run_oem_hooks():
"""Run hook scripts from /usr/lib/oem-config/post-install."""
hookdir = '/usr/lib/oem-config/post-install'
if os.path.isdir(hookdir):
# Exclude hooks containing '.', so that *.dpkg-* et al are avoided.
hooks = filter(lambda entry: '.' not in entry, os.listdir(hookdir))
child_env = dict(os.environ)
child_env['DEBIAN_FRONTEND'] = 'noninteractive'
if 'DEBIAN_HAS_FRONTEND' in child_env:
del child_env['DEBIAN_HAS_FRONTEND']
for hookentry in hooks:
hook = os.path.join(hookdir, hookentry)
if os.access(hook, os.X_OK):
# Errors are ignored at present, although this may change.
subprocess.call([hook], env=child_env)
def main(oem_config):
usage = '%prog [options] [frontend]'
parser = optparse.OptionParser(usage=usage, version=VERSION)
parser.set_defaults(
debug=('UBIQUITY_DEBUG' in os.environ),
debug_pdb=False,
cdebconf=False,
automatic=False,
query=False,
migration_assistant=(not oem_config))
parser.add_option('-d', '--debug', dest='debug', action='store_true',
help='debug mode (warning: passwords will be logged!)')
parser.add_option('--pdb', dest='debug_pdb', action='store_true',
help='drop into Python debugger on a crash')
parser.add_option('--cdebconf', dest='cdebconf', action='store_true',
help='use cdebconf instead of debconf (experimental)')
if not oem_config:
parser.add_option('--no-migration-assistant', dest='migration_assistant',
action='store_false',
help='disable Migration Assistant')
parser.add_option('--automatic', dest='automatic', action='store_true',
help='do not ignore the "seen" flag (useful for ' \
'unattended installations).')
parser.add_option('--only', dest='only', action='store_true',
help='tell the application that it is the only desktop ' \
'program running so that it can customize its UI to ' \
'better suit a minimal environment.')
parser.add_option('-q', '--query', dest='query', action='store_true',
help='find out which frontend will be used by default')
(options, args) = parser.parse_args()
if options.debug:
os.environ['UBIQUITY_DEBUG'] = '1'
if options.debug_pdb:
os.environ['UBIQUITY_DEBUG_PDB'] = '1'
if options.cdebconf:
# Note that this needs to be set before DebconfCommunicate is
# imported by anything.
os.environ['DEBCONF_USE_CDEBCONF'] = '1'
prepend_path('/usr/lib/cdebconf')
prepend_path('/usr/lib/ubiquity/compat')
if options.automatic:
os.environ['UBIQUITY_AUTOMATIC'] = '1'
if options.migration_assistant:
os.environ['UBIQUITY_MIGRATION_ASSISTANT'] = '1'
if options.only:
os.environ['UBIQUITY_ONLY'] = '1'
if oem_config:
os.environ['UBIQUITY_OEM_USER_CONFIG'] = '1'
global TARGET
TARGET = ''
acquire_lock()
if not os.path.exists('/var/log/installer'):
os.makedirs('/var/log/installer')
syslog.openlog('ubiquity', syslog.LOG_NOWAIT | syslog.LOG_PID)
if oem_config:
syslog.syslog("Ubiquity %s (oem-config)" % VERSION)
else:
syslog.syslog("Ubiquity %s" % VERSION)
version_file = open('/var/log/installer/version', 'w')
print >>version_file, 'ubiquity %s' % VERSION
version_file.close()
if 'UBIQUITY_DEBUG' in os.environ:
if 'UBIQUITY_DEBUG_CORE' not in os.environ:
os.environ['UBIQUITY_DEBUG_CORE'] = '1'
if 'DEBCONF_DEBUG' not in os.environ:
os.environ['DEBCONF_DEBUG'] = 'developer|filter'
# The frontend should take care of displaying a helpful message if
# we are being run without root privileges.
if not (options.query and args and args[0] == 'noninteractive'):
try:
if oem_config:
logfile = '/var/log/oem-config.log'
else:
logfile = '/var/log/installer/debug'
log = os.open(logfile, os.O_WRONLY | os.O_CREAT | os.O_APPEND)
os.dup2(log, 2)
os.close(log)
sys.stderr = os.fdopen(2, 'a', 1)
if oem_config:
print >>sys.stderr, "Ubiquity %s (oem-config)" % VERSION
else:
print >>sys.stderr, "Ubiquity %s" % VERSION
except (IOError, OSError), err:
if err.errno != errno.EACCES:
raise
# Default to enabling internal (non-debconf) debugging except for when
# using --automatic.
if 'UBIQUITY_DEBUG_CORE' not in os.environ:
if options.automatic:
os.environ['UBIQUITY_DEBUG_CORE'] = '1'
# Clean up old state.
for name in ('apt-installed', 'apt-install-direct', 'remove-kernels'):
path = os.path.join('/var/lib/ubiquity', name)
if os.path.exists(path):
os.unlink(path)
shutil.rmtree("/var/lib/partman", ignore_errors=True)
if oem_config and not options.query:
disable_autologin()
if args:
install(args[0], query=options.query)
else:
install(query=options.query)
if oem_config:
run_oem_hooks()
im_switch.kill_im()
if __name__ == '__main__':
# Are we running as ubiquity or oem-config?
oem_config = False
script_name = os.path.basename(sys.argv[0])
if script_name == 'oem-config':
oem_config = True
main(oem_config)
# vim:ai:et:sts=4:tw=80:sw=4: